﻿namespace WebPacker.Tests.VersionGenerators
{
	using System;
	using NUnit.Framework;
	using WebPacker.VersionGenerators;

	[TestFixture]
	public class VersionGeneratorCollectionTest
	{
		[Test]
		public void AddNullTest()
		{
			var collection = new VersionGeneratorCollection();
			Assert.Throws<ArgumentNullException>(() => collection.Add(null));
		}

		[Test]
		public void AddTest()
		{
			var collection = new VersionGeneratorCollection();
			collection.Add(new ManualVersionGenerator() { Name = "manual" });
			Assert.AreEqual(1, collection.Count);
		}

		[Test]
		public void AddComplexTest()
		{
			var collection = new VersionGeneratorCollection();
			collection.Add(new ManualVersionGenerator() { Name = "1" });
			collection.Add(new ManualVersionGenerator() { Name = "2" });
			collection.Add(new Md5VersionGenerator() { Name = "3" });
			Assert.AreEqual(3, collection.Count);
		}

		[Test]
		public void AddRangeTest()
		{
			var collection = new VersionGeneratorCollection();
			var filters = GetTestGenerators();
			collection.AddRange(filters);
			Assert.AreEqual(filters.Length, collection.Count);
		}

		[Test]
		public void AddUniqueConstraintTest()
		{
			var collection = new VersionGeneratorCollection();
			collection.Add(new ManualVersionGenerator { Name = "1" });
			Assert.Throws<ArgumentException>(() => collection.Add(new ManualVersionGenerator { Name = "1" }));
			Assert.AreEqual(1, collection.Count);
		}

		[Test]
		public void GetItemTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);

			foreach (var generator in generators)
			{
				Assert.AreSame(generator, collection.GetItem(generator.Name));
			}
		}

		[Test]
		public void ContainsTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);

			foreach (var generator in generators)
			{
				Assert.IsTrue(collection.Contains(generator.Name));
			}
		}

		[Test]
		public void TryGetItemTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);

			foreach (var expected in generators)
			{
				IVersionGenerator actual;
				Assert.IsTrue(collection.TryGetItem(expected.Name, out actual));
				Assert.AreSame(expected, actual);
			}
		}

		[Test]
		public void GetItemFailedTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);
			Assert.Throws<ArgumentException>(() => collection.GetItem("unknown"));
		}

		[Test]
		public void TryGetItemFailedTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);
			IVersionGenerator actual;
			Assert.IsFalse(collection.TryGetItem("unknown", out actual));
			Assert.IsNull(actual);
		}

		[Test]
		public void ContainsFailedTest()
		{
			var generators = GetTestGenerators();
			var collection = new VersionGeneratorCollection();
			collection.AddRange(generators);
			Assert.IsFalse(collection.Contains("unknown"));
		}

		[Test]
		public void RemoveTest()
		{
			var collection = new VersionGeneratorCollection();
			collection.Add(new ManualVersionGenerator() { Name = "1" });
			Assert.IsTrue(collection.Remove("1"));
			Assert.AreEqual(0, collection.Count);
		}

		[Test]
		public void RemoveFailedTest()
		{
			var collection = new VersionGeneratorCollection();
			collection.Add(new ManualVersionGenerator() { Name = "1" });
			Assert.IsFalse(collection.Remove("2"));
			Assert.AreEqual(1, collection.Count);
		}

		private IVersionGenerator[] GetTestGenerators()
		{
			return new IVersionGenerator[]
			{
				new ManualVersionGenerator(),
				new Md5VersionGenerator(),
				new LastModifiedVersionGenerator()
			};
		}
	}
}
